#include "encrypter.h"
#include <stdlib.h>
#include <string.h>

//allocating space for encrypter object
encrypter *enc_new()
{
	encrypter *enc = (encrypter*)malloc(sizeof(encrypter));
	
	enc->_ascInput = 0;
	enc->_ascKey = 0;
	enc->_inputLen = 0;
	enc->_keyLen = 0;
	
	return enc;
}

void enc_free(encrypter *obj)
{
	if (obj->_ascInput != 0) free(obj->_ascInput);
	if (obj->_ascKey != 0) free(obj->_ascKey);
	
	obj->_ascInput = 0;
	obj->_ascKey = 0;
}

//Map the A-Z 0-9 to integer value, 0-35
void _map_to_ascii(encrypter *obj, char *input, char *key)
{
	obj->_inputLen = strlen(input);
	obj->_keyLen = strlen(key);
	
	if (obj->_ascInput != 0)
		free(obj->_ascInput);
	if (obj->_ascKey != 0)
		free(obj->_ascKey);
	
	obj->_ascInput = (int*)malloc(sizeof(int) * obj->_inputLen);
	obj->_ascKey = (int*)malloc(sizeof(int) * obj->_keyLen);
	
	int i = 0;
	for (i = 0; i < obj->_inputLen; i++)
	{
		if ((int)input[i] >= 48 && (int)input[i] <= 57)
			obj->_ascInput[i] = ((int)toupper(input[i])) - 22;
		else
			obj->_ascInput[i] = ((int)toupper(input[i])) - 65;
	}
	
	for (i = 0; i < obj->_keyLen; i++)
	{
		if ((int)key[i] >= 48 && (int)key[i] <= 57)
			obj->_ascKey[i] = ((int)toupper(key[i])) - 22;
		else
			obj->_ascKey[i] = ((int)toupper(key[i])) - 65;
	}
}

char *enc_encrypt(encrypter *obj, char *input, char *key)
{
	_map_to_ascii(obj, input, key);
	char *output = (char*)malloc(sizeof(char) * (obj->_inputLen + 1));
	
	int i = 0;
	int j = 0;
	for (i = 0, j = 0; i < obj->_inputLen; i++, j++)
	{
		if (j >= obj->_keyLen) j = 0;
		if (((obj->_ascInput[i] + obj->_ascKey[j]) % 36) > 25)
			output[i] = tolower(((obj->_ascInput[i] + obj->_ascKey[j]) % 36) + 22);
		else
			output[i] = tolower(((obj->_ascInput[i] + obj->_ascKey[j]) % 36) + 65);
	}
	
	output[obj->_inputLen] = '\0';
	
	if (obj->_ascInput != 0)
	{
		free(obj->_ascInput);
		obj->_ascInput = 0;
	}
	if (obj->_ascKey != 0)
	{
		free(obj->_ascKey);
		obj->_ascKey = 0;
	}
	
	return output;
}

char *enc_decrypt(encrypter *obj, char *input, char *key)
{
	int value = 0;
	_map_to_ascii(obj, input, key);
	char *output = (char*)malloc(sizeof(char) * (obj->_inputLen + 1));
	
	int i = 0;
	int j = 0;
	for (i = 0, j = 0; i < obj->_inputLen; i++, j++)
	{
		if (j >= obj->_keyLen) j = 0;
		
		if (obj->_ascInput[i] - obj->_ascKey[j] < 0)
			value = 36 - (-(obj->_ascInput[i] - obj->_ascKey[j]));
		else
			value = obj->_ascInput[i] - obj->_ascKey[j];
		
		if (value > 25)
			output[i] = tolower(value + 22);
		else
			output[i] = tolower(value + 65);
	}

	output[obj->_inputLen] = '\0';
	
	if (obj->_ascInput != 0)
	{
		free(obj->_ascInput);
		obj->_ascInput = 0;
	}
	if (obj->_ascKey != 0)
	{
		free(obj->_ascKey);
		obj->_ascKey = 0;
	}
	
	return output;
}
